<template>
    <div class="upload-audio-container">

        <div class="upload-audio-item">

            <div class="upload-audio-content">

                <n-form ref="formRef" class="audioInfoForm" :model="uploadAudioForm" :rules="rules">
                    <n-form-item path="audioName" label="音频名称：">
                        <n-input v-model:value="uploadAudioForm.audioName" type="text" placeholder="请输入音频名称" />
                    </n-form-item>
                    <n-form-item path="audioVersion" label="音频来源：">
                        <n-input v-model:value="uploadAudioForm.audioVersion" type="text" placeholder="请输入音频来源（xx专辑、xx演唱会）" />
                    </n-form-item>
                    <n-form-item path="singer" label="歌手：">
                        <n-input v-model:value="uploadAudioForm.singer" type="text" placeholder="请输入歌手名称" />
                    </n-form-item>
                    <n-form-item path="write" label="作词：">
                        <n-input v-model:value="uploadAudioForm.write" type="text" placeholder="请输入作曲家" />
                    </n-form-item>
                    <n-form-item path="uploader" label="上传者：">
                        <n-input v-model:value="uploadAudioForm.uploader" type="text" disabled placeholder="请核对上传者名称" />
                    </n-form-item>
                    <n-form-item path="uploaderId" label="上传者Id：">
                        <n-input v-model:value="uploadAudioForm.uploaderId" type="text" disabled placeholder="请核对上传者Id" />
                    </n-form-item>
                </n-form>

                <div class="audioResources">

                    <div class="audioLocalResources">

                        <div style="font-size: 1.5rem;margin-bottom: 10px;display: flex;align-items: center;justify-content: space-around; width: 100%;">
                            本地上传模式&nbsp;&nbsp;&nbsp;&nbsp;
                            <n-button dashed color="#ff1a66" @click="uploadAudioBtn">确认上传</n-button>
                        </div>

                        <n-upload ref="uploadAudioRef" name="audio" class="upload-audio upload-item" v-model:file-list="uploadAudioFile" :data="uploadAudioForm" :max="1" directory-dnd accept="audio/*" :default-upload="false"
                            :headers="{ token: userInfo.token }" :action="uploadAudio" :on-change="handleAudioUploadPending" @finish="handleAudioUploadFinish">
                            <n-upload-dragger>
                                <div style="margin-bottom: 12px">
                                    <n-icon size="35" :depth="1">
                                        <FileMusic />
                                    </n-icon>
                                </div>
                                <n-text style="font-size: 16px">
                                    点击或者拖动文件到该区域来上传音频文件（必须项）
                                </n-text>
                            </n-upload-dragger>
                        </n-upload>

                        <n-upload ref="uploadCoverRef" name="cover" class="upload-cover upload-item" v-model:file-list="uploadCoverFile" :data="uploadAudioForm" :max="1" directory-dnd accept="image/*" :default-upload="false"
                            :headers="{ token: userInfo.token }" :action="uploadAudioCover" :on-change="handleCoverUploadPending" @finish="handleCoverUploadFinish">
                            <n-upload-dragger>
                                <div style="margin-bottom: 12px">
                                    <n-icon size="35" :depth="1">
                                        <PictureTwotone />
                                    </n-icon>
                                </div>
                                <n-text style="font-size: 16px">
                                    点击或者拖动文件到该区域来上传音频封面（必须项）
                                </n-text>
                            </n-upload-dragger>
                        </n-upload>

                        <n-upload ref="uploadLyricRef" name="lyric" class="upload-lyric upload-item" v-model:file-list="uploadLyricFile" :data="uploadAudioForm" :max="1" directory-dnd :default-upload="false" :action="uploadAudioLyric"
                            :headers="{ token: userInfo.token }" :on-change="handleLyricUploadPending" @finish="handleLyricUploadFinish">
                            <n-upload-dragger>
                                <div style="margin-bottom: 12px">
                                    <n-icon size="35" :depth="1">
                                        <FileWordOutlined />
                                    </n-icon>
                                </div>
                                <n-text style="font-size: 16px">
                                    点击或者拖动文件到该区域来上传音频歌词（必须项）
                                </n-text>
                            </n-upload-dragger>
                        </n-upload>

                        <n-upload ref="uploadMvRef" name="mv" class="upload-mv upload-item" :max="1" directory-dnd accept="video/*" :default-upload="false" :action="uploadAudio">
                            <n-upload-dragger>
                                <div style="margin-bottom: 12px">
                                    <n-icon size="35" :depth="1">
                                        <DocumentVideo />
                                    </n-icon>
                                </div>
                                <n-text style="font-size: 16px">
                                    点击或者拖动文件到该区域来上传音频MV（非必须项）
                                </n-text>
                            </n-upload-dragger>
                        </n-upload>

                    </div>

                    <div class="audioBiLiBiLiResources">

                        <div style="font-size: 1.5rem;margin-bottom: 10px;display: flex;align-items: center;justify-content: space-around; width: 100%;">
                            B站外链模式（分享嵌入代码）：&nbsp;&nbsp;&nbsp;&nbsp;
                            <n-button dashed color="#ff1a66" @click="">确认上传</n-button>
                        </div>

                        <div class="audioBiLiBiLiResources-info">
                            <n-input v-model:value="outsideAudioLink" type="textarea" style="height: 200px;margin-right: 20px;"
                                placeholder='嵌入代码外链的地址，它看起来像这样（<iframe src="//player.bilibili.com/player.html?aid=611153282&bvid=BV1R84y1c7By&cid=1058320855&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe>）'
                                @blur="showPreview" />
                        </div>

                        <div class="audioBiLiBiLiResources-preview">
                            <iframe v-if="showBV" :src="_outsideAudioLink" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="420" height="300">
                            </iframe>
                        </div>

                    </div>

                </div>

            </div>

        </div>

    </div>
</template>
    
<script setup lang='ts'>
import { FileMusic } from '@vicons/tabler'
import { DocumentVideo } from '@vicons/carbon'
import { FileWordOutlined, PictureTwotone } from '@vicons/antd'
import { uploadAudio, uploadAudioCover, uploadAudioLyric } from '../../ajax/index'
import { ref, onBeforeMount } from 'vue'
import { useMessage } from 'naive-ui'
import { matchMusicExt, matchMusicCoverExt, matchMusicLyricExt, getMusicDuration } from '../../util/calculate'
import type { FormInst, FormRules, UploadFileInfo, UploadInst } from 'naive-ui'
import { userInfoStore, useSystemConfigStore } from '../../store/index'
import { useRouter } from 'vue-router';

onBeforeMount(() => {
    if (userInfo.roles !== 'admin' && userInfo.roles !== 'root') {
        useSystemConfig.changeSetPage('systemConfig')
        router.replace({ name: 'systemConfig' })
        message.warning('没有权限用户禁止使用此功能，已跳转至系统配置')
    }
})

const message = useMessage()
const useSystemConfig = useSystemConfigStore()
const userInfo = userInfoStore()
const router = useRouter()

const formRef = ref<FormInst | null>(null)
const uploadAudioForm = ref({
    audioName: '', audioVersion: '', duration: '', singer: '', write: '',
    uploader: userInfo.username, uploaderId: userInfo.uid, audioId: ''
})
const uploadAudioRef = ref<UploadInst | null>(null)
const uploadAudioFile = ref<UploadFileInfo[]>([])
const uploadCoverRef = ref<UploadInst | null>(null)
const uploadCoverFile = ref<UploadFileInfo[]>([])
const uploadLyricRef = ref<UploadInst | null>(null)
const uploadLyricFile = ref<UploadFileInfo[]>([])
const uploadMvRef = ref<UploadInst | null>(null)


const outsideAudioLink = ref('')
const _outsideAudioLink = ref('')
const showBV = ref(false)


// 上传音频的表单信息验证规则
const rules: FormRules = {
    audioName: [
        {
            required: true,
            message: '音频名称不能为空',
            trigger: ['input', 'blur']
        }
    ],
    audioVersion: [
        {
            required: true,
            message: '音频来源不能为空',
            trigger: ['input', 'blur']
        }
    ],
    singer: [
        {
            required: true,
            message: '歌手姓名不能为空',
            trigger: ['input', 'blur']
        }
    ],
    write: [
        {
            required: true,
            message: '作曲姓名不能为空',
            trigger: ['input', 'blur']
        }
    ],
}

// 音频文件发生变化的回调
const handleAudioUploadPending = async (options: { file: UploadFileInfo, fileList: Array<UploadFileInfo>, event?: Event }) => {
    if (options.fileList.length !== 0) { // 有文件时才触发
        // 音频文件格式验证
        const auth = matchMusicExt(options.file)
        if (auth) {
            // 获取音频时长
            const duration = await getMusicDuration(options.file)
            uploadAudioForm.value.duration = duration
        } else {
            options.fileList.length = 0
            message.error("不支持的音频类型！")
        }
    } else {
        uploadAudioForm.value.duration = ''
    }
}
// 音频封面文件发生变化的回调
const handleCoverUploadPending = async (options: { file: UploadFileInfo, fileList: Array<UploadFileInfo>, event?: Event }) => {
    if (options.fileList.length !== 0) { // 有文件时才触发
        // 音频封面格式验证
        const auth = matchMusicCoverExt(options.file)
        if (!auth) {
            options.fileList.length = 0
            message.error("不支持的音频封面类型！")
        }
    }
}
// 音频歌词文件发生变化的回调
const handleLyricUploadPending = async (options: { file: UploadFileInfo, fileList: Array<UploadFileInfo>, event?: Event }) => {
    if (options.fileList.length !== 0) { // 有文件时才触发
        // 音频封面格式验证
        const auth = matchMusicLyricExt(options.file)
        if (!auth) {
            options.fileList.length = 0
            message.error("不支持的音频歌词类型！")
        }
    }
}

// 音频上传完毕
const handleAudioUploadFinish = (options: { file: UploadFileInfo, event?: ProgressEvent }) => {
    const { audioId } = JSON.parse((options.event?.target as XMLHttpRequest).response)
    uploadAudioForm.value.audioId = audioId
    message.info("音频上传完毕，正在上传封面、歌词。。。")
    uploadCoverRef.value?.submit()
    uploadLyricRef.value?.submit()
}
// 封面上传完毕
const handleCoverUploadFinish = () => {
    message.info("封面上传完毕")
}
// 歌词上传完毕
const handleLyricUploadFinish = () => {
    message.info("歌词上传完毕")
    message.info("本次音乐全部上传完毕，已获得对应的等级奖励")
}

// 上传音频/歌词/封面
const uploadAudioBtn = () => {

    formRef.value?.validate((errors) => {
        if (!errors) {
            if (uploadAudioFile.value.length !== 0 && uploadCoverFile.value.length !== 0 && uploadLyricFile.value.length !== 0) {
                message.info("音频上传中。。。")
                uploadAudioRef.value?.submit()
            } else {
                message.error("上传的音频表单数据或文件数据不完整，请继续填写/上传本地文件")
            }
        } else {
            message.error("上传的音频表单数据或文件数据不完整，请继续填写/上传本地文件")
        }
    })

}




// B站预览
const showPreview = () => {
    if (outsideAudioLink.value !== '') {

        const reg = new RegExp(/src=".*?"/, 'g')
        const flag = reg.test(outsideAudioLink.value)

        if (flag) {
            let tmp = outsideAudioLink.value.split('src="')[1]
            tmp = tmp.split('" ')[0]
            _outsideAudioLink.value = tmp
            showBV.value = true
        } else {
            message.warning('外链格式错误，重新点击B站分享内嵌代码')
            showBV.value = false
        }

    } else {
        showBV.value = false
    }
}


</script>
    
<style scoped lang="less">
.upload-audio-container {
    width: 100%;

    .upload-audio-item {

        display: flex;
        flex-wrap: wrap;

        .upload-audio-content {
            display: flex;
            flex-wrap: wrap;
            width: 100%;

            .audioInfoForm {
                width: 30%;
            }

            .audioResources {
                width: 70%;
                display: flex;
                flex-wrap: wrap;
                justify-content: space-around;
                align-items: center;
                overflow: hidden;

                .audioLocalResources {
                    display: flex;
                    flex-wrap: wrap;
                    justify-content: space-around;

                    .upload-item {
                        width: 20%;
                    }

                }

                .audioBiLiBiLiResources {
                    height: 320px;
                    display: flex;
                    flex-wrap: wrap;
                    justify-content: space-around;

                    .audioBiLiBiLiResources-info {
                        width: 35%;
                        display: flex;
                        flex-wrap: wrap;
                        align-items: center;
                    }
                }

            }

        }

    }


}
</style>